﻿using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Sonce.Editor.Tools
{
    public class HandTool : IEditorTool
    {
        #region Members
        private HandTypes type = HandTypes.Select;
        #endregion

        #region Constructor
        public HandTool()
        {
        }
        #endregion

        #region Properties
        public HandTypes Type
        {
            get
            {
                return this.type;
            }
            set
            {
                this.type = value;
            }
        }

        public SelectionMode Mode
        {
            get
            {
                //TODO: Change cursor appearence on SelectionMode change
                if ((Keyboard.Modifiers & ModifierKeys.Control & ModifierKeys.Shift) != 0)
                {
                    return SelectionMode.Add;
                }
                else if ((Keyboard.Modifiers & ModifierKeys.Control & ModifierKeys.Alt) != 0)
                {
                    return SelectionMode.Remove;
                }
                else if ((Keyboard.Modifiers & ModifierKeys.Control) != 0)
                {
                    return SelectionMode.Toggle;
                }
                else
                {
                    return SelectionMode.Multiple;
                }
            }
        }

        public double Tolerance
        {
            get
            {
                return 10.0;
            }
        }
        #endregion

        #region IEditorTool Members
        public Editor Editor
        {
            get;
            set;
        }

        public bool KeyDown(Key key)
        {
            bool handled = false;
            switch (key)
            {
                //Merge selected nodes
                case Key.M:
                    handled = true;
                    break;
            }
            return handled;
        }

        public bool KeyUp(Key key)
        {
            return false;
        }

        public bool MouseDown(Point position)
        {
            if (this.Editor.IsHoldingNode)
            {
                //Change cursor when holding node to avoid flickering
                this.Editor.LayerNodes.Cursor = Cursors.Hand;
            }

            return true;
        }

        public bool MouseUp(Point position)
        {
            if (this.Editor.IsHoldingNode)
            {
                this.Editor.IsHoldingNode = false;
                //TODO: Update selection if selected
            }
            else if (this.Editor.StartPoint == position)
            {
                #region Click
                switch (this.Mode)
                {
                    //case SelectionMode.Single:
                    case SelectionMode.Multiple:
                        this.Editor.SelectionManager.UnselectAll();
                        this.Editor.SelectionManager.Select(position, this.Tolerance);
                        break;

                    case SelectionMode.Add:
                        this.Editor.SelectionManager.Select(position, this.Tolerance);
                        break;

                    case SelectionMode.Remove:
                        this.Editor.SelectionManager.Unselect(position, this.Tolerance);
                        break;

                    case SelectionMode.Toggle:
                        this.Editor.SelectionManager.ToggleSelect(position, this.Tolerance);
                        break;
                }
                #endregion
            }
            else
            {
                bool intersect = (position.X - this.Editor.StartPoint.X < 0); //Intersect or contain
                Rect region = new Rect(this.Editor.StartPoint, position);

                #region Drag
                switch (this.Mode)
                {
                    //case SelectionMode.Single:
                    case SelectionMode.Multiple:
                        this.Editor.SelectionManager.UnselectAll();
                        this.Editor.SelectionManager.Select(region, intersect);
                        break;

                    case SelectionMode.Add:
                        this.Editor.SelectionManager.Select(region, intersect);
                        break;

                    case SelectionMode.Remove:
                        this.Editor.SelectionManager.Unselect(region, intersect);
                        break;

                    case SelectionMode.Toggle:
                        this.Editor.SelectionManager.ToggleSelect(region, intersect);
                        break;
                }
                #endregion

                this.Editor.LayerPreview.Clear();
                this.Editor.LayerFloat.Clear();
                this.Editor.LayerNodes.Cursor = Cursors.None;
            }

            return true;
        }

        Point lastMovePoint;

        public bool MouseMove(Point position, bool isMouseDown)
        {
            if (this.Editor.SelectionManager.SelectedElements.Count == 0)
            {
                bool intersect = true;
                Rect region = Helper.GetRegion(position, 10);

                if (isMouseDown)
                {
                    //if (this.Editor.IsHoldingNode)
                    //{
                    //this.Editor.HoldingNode.Position = position;

                    ////int nodePosition = -1;
                    ////List<Node> nodes = new List<Node>();
                    //foreach (UIElement element in this.Editor.LayerNodes.Children)
                    //{
                    //    if (element is Node)
                    //    {
                    //        Node node = element as Node;
                    //        //nodes.Add(node);
                    //        if (node == this.Editor.HoldingNode)
                    //        {
                    //            //nodePosition = nodes.Count - 1;
                    //            node.Position = position;
                    //            break;
                    //        }
                    //    }
                    //}

                    //if (nodes.Count > 0 && nodePosition >= 0 && nodePosition < nodes.Count)
                    //{
                    //    Node node = nodes[nodePosition];
                    //    Node prevNode = (nodePosition > 1 ? nodes[nodePosition - 1] : null);
                    //    Node nextNode = (nodePosition < nodes.Count - 1 ? nodes[nodePosition - 1] : null);
                    //    node.Visibility = Visibility.Collapsed;
                    //    node = new Node(node.Position);
                    //    this.Editor.LayerPreview.Clear();
                    //    this.Editor.LayerPreview.Draw(node.Position, node);
                    //    if (prevNode != null)
                    //    {
                    //        this.Editor.LayerPreview.StartPolyLine(prevNode.Position);
                    //        this.Editor.LayerPreview.ContinuePolyLine(node.Position);
                    //    }
                    //    if (nextNode != null)
                    //    {
                    //        if (prevNode == null)
                    //            this.Editor.LayerPreview.StartPolyLine(node.Position);
                    //        this.Editor.LayerPreview.ContinuePolyLine(nextNode.Position);
                    //    }
                    //}

                    //if (this.Editor.HoldingNode.Segment != null)
                    //{
                    //    if (this.Editor.HoldingNode.Segment is LineSegment)
                    //    {
                    //        ((LineSegment)this.Editor.HoldingNode.Segment).Point = position;
                    //    }
                    //    else if (this.Editor.HoldingNode.Segment is PathFigure)
                    //    {
                    //        ((PathFigure)this.Editor.HoldingNode.Segment).StartPoint = position;
                    //    }
                    //}
                    //}
                    //else 

                    ShapeTool shapeTool = new ShapeTool() { Editor = this.Editor };
                    if (position.X - this.Editor.StartPoint.X > 0)
                    {
                        //Contains in rectangle
                        this.Editor.LayerFloat.StrokeBrush = new SolidColorBrush(Colors.Green);
                        this.Editor.LayerFloat.FillBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x7F, 0x00));
                        Rectangle rectangle = shapeTool.DrawRectangle(this.Editor.LayerFloat, this.Editor.StartPoint, position);
                        region = new Rect(rectangle.Margin.Left, rectangle.Margin.Top, rectangle.Width, rectangle.Height);
                        intersect = false;
                    }
                    else
                    {
                        //Intersects in rectangle
                        this.Editor.LayerFloat.StrokeBrush = new SolidColorBrush(Colors.Blue);
                        this.Editor.LayerFloat.FillBrush = new SolidColorBrush(Color.FromArgb(0x3F, 0x00, 0x00, 0x7F));
                        Rectangle rectangle = shapeTool.DrawRectangle(this.Editor.LayerFloat, this.Editor.StartPoint, position);
                        region = new Rect(rectangle.Margin.Left, rectangle.Margin.Top, rectangle.Width, rectangle.Height);
                        intersect = true;
                    }
                }

                this.Editor.LayerHighlight.Clear();
                this.Editor.SelectionManager.HighlightElementsAt(this.Editor.LayerHighlight, region, intersect);
            }
            else
            {
                //this.Editor.LayoutManager.Move(this.Editor.SelectionManager.SelectedElements[0], position, false);
            }

            return true;
        }

        public bool MouseEnter()
        {
            return false;
        }

        public bool MouseLeave()
        {
            return false;
        }

        public bool MouseWheel(int delta)
        {
            return false;
        }
        #endregion
    }
}
